﻿namespace YidanSoft.Library.EditorUtility.Collections
{
    using System;
    using System.Collections;
    using System.Runtime.CompilerServices;
    using System.Threading;

    public class CollectionWithEvents : CollectionBase
    {
        private CollectionClear Cleared;
        private CollectionClear Clearing;
        private CollectionChange Inserted;
        private CollectionChange Inserting;
        private CollectionChange Removed;
        private CollectionChange Removing;

        public event CollectionClear Cleared
        {
            add
            {
                CollectionClear clear2;
                CollectionClear cleared = this.Cleared;
                do
                {
                    clear2 = cleared;
                    CollectionClear clear3 = (CollectionClear) Delegate.Combine(clear2, value);
                    cleared = Interlocked.CompareExchange<CollectionClear>(ref this.Cleared, clear3, clear2);
                }
                while (cleared != clear2);
            }
            remove
            {
                CollectionClear clear2;
                CollectionClear cleared = this.Cleared;
                do
                {
                    clear2 = cleared;
                    CollectionClear clear3 = (CollectionClear) Delegate.Remove(clear2, value);
                    cleared = Interlocked.CompareExchange<CollectionClear>(ref this.Cleared, clear3, clear2);
                }
                while (cleared != clear2);
            }
        }

        public event CollectionClear Clearing
        {
            add
            {
                CollectionClear clear2;
                CollectionClear clearing = this.Clearing;
                do
                {
                    clear2 = clearing;
                    CollectionClear clear3 = (CollectionClear) Delegate.Combine(clear2, value);
                    clearing = Interlocked.CompareExchange<CollectionClear>(ref this.Clearing, clear3, clear2);
                }
                while (clearing != clear2);
            }
            remove
            {
                CollectionClear clear2;
                CollectionClear clearing = this.Clearing;
                do
                {
                    clear2 = clearing;
                    CollectionClear clear3 = (CollectionClear) Delegate.Remove(clear2, value);
                    clearing = Interlocked.CompareExchange<CollectionClear>(ref this.Clearing, clear3, clear2);
                }
                while (clearing != clear2);
            }
        }

        public event CollectionChange Inserted
        {
            add
            {
                CollectionChange change2;
                CollectionChange inserted = this.Inserted;
                do
                {
                    change2 = inserted;
                    CollectionChange change3 = (CollectionChange) Delegate.Combine(change2, value);
                    inserted = Interlocked.CompareExchange<CollectionChange>(ref this.Inserted, change3, change2);
                }
                while (inserted != change2);
            }
            remove
            {
                CollectionChange change2;
                CollectionChange inserted = this.Inserted;
                do
                {
                    change2 = inserted;
                    CollectionChange change3 = (CollectionChange) Delegate.Remove(change2, value);
                    inserted = Interlocked.CompareExchange<CollectionChange>(ref this.Inserted, change3, change2);
                }
                while (inserted != change2);
            }
        }

        public event CollectionChange Inserting
        {
            add
            {
                CollectionChange change2;
                CollectionChange inserting = this.Inserting;
                do
                {
                    change2 = inserting;
                    CollectionChange change3 = (CollectionChange) Delegate.Combine(change2, value);
                    inserting = Interlocked.CompareExchange<CollectionChange>(ref this.Inserting, change3, change2);
                }
                while (inserting != change2);
            }
            remove
            {
                CollectionChange change2;
                CollectionChange inserting = this.Inserting;
                do
                {
                    change2 = inserting;
                    CollectionChange change3 = (CollectionChange) Delegate.Remove(change2, value);
                    inserting = Interlocked.CompareExchange<CollectionChange>(ref this.Inserting, change3, change2);
                }
                while (inserting != change2);
            }
        }

        public event CollectionChange Removed
        {
            add
            {
                CollectionChange change2;
                CollectionChange removed = this.Removed;
                do
                {
                    change2 = removed;
                    CollectionChange change3 = (CollectionChange) Delegate.Combine(change2, value);
                    removed = Interlocked.CompareExchange<CollectionChange>(ref this.Removed, change3, change2);
                }
                while (removed != change2);
            }
            remove
            {
                CollectionChange change2;
                CollectionChange removed = this.Removed;
                do
                {
                    change2 = removed;
                    CollectionChange change3 = (CollectionChange) Delegate.Remove(change2, value);
                    removed = Interlocked.CompareExchange<CollectionChange>(ref this.Removed, change3, change2);
                }
                while (removed != change2);
            }
        }

        public event CollectionChange Removing
        {
            add
            {
                CollectionChange change2;
                CollectionChange removing = this.Removing;
                do
                {
                    change2 = removing;
                    CollectionChange change3 = (CollectionChange) Delegate.Combine(change2, value);
                    removing = Interlocked.CompareExchange<CollectionChange>(ref this.Removing, change3, change2);
                }
                while (removing != change2);
            }
            remove
            {
                CollectionChange change2;
                CollectionChange removing = this.Removing;
                do
                {
                    change2 = removing;
                    CollectionChange change3 = (CollectionChange) Delegate.Remove(change2, value);
                    removing = Interlocked.CompareExchange<CollectionChange>(ref this.Removing, change3, change2);
                }
                while (removing != change2);
            }
        }

        protected int IndexOf(object value)
        {
            return base.List.IndexOf(value);
        }

        protected override void OnClear()
        {
            if (this.Clearing != null)
            {
                this.Clearing();
            }
        }

        protected override void OnClearComplete()
        {
            if (this.Cleared != null)
            {
                this.Cleared();
            }
        }

        protected override void OnInsert(int index, object value)
        {
            if (this.Inserting != null)
            {
                this.Inserting(index, value);
            }
        }

        protected override void OnInsertComplete(int index, object value)
        {
            if (this.Inserted != null)
            {
                this.Inserted(index, value);
            }
        }

        protected override void OnRemove(int index, object value)
        {
            if (this.Removing != null)
            {
                this.Removing(index, value);
            }
        }

        protected override void OnRemoveComplete(int index, object value)
        {
            if (this.Removed != null)
            {
                this.Removed(index, value);
            }
        }

        public delegate void CollectionChange(int index, object value);

        public delegate void CollectionClear();
    }
}

